add STM32 backend (STM32duino / Arduino_Core_STM32)#359
Conversation
|
Thanks for the great code. Github tests still not passing. Copilot says: I'll get the logs for the failing job and analyze the issue.Now let me check the RampCalculator.h file to understand the issue:## Solution for Failing Job 76782123704 The compilation is failing because of undeclared variables in
Root CauseThese variables are referenced in the macros at lines 114-116 but are not declared as member variables of the SolutionYou need to add the missing member variables to the struct ramp_config_s {
// ... existing members ...
// Add these new members:
uint8_t log2_timer_freq;
uint8_t log2_timer_freq_div_sqrt_of_2;
uint16_t log2_timer_freq_square_div_2;
// ... rest of struct ...
};Alternatively, if these values should be calculated or initialized elsewhere, ensure they are properly initialized in the The secondary issue about narrowing conversion warnings in |
|
The code still does not compile. There is a subtle indirect requirement, which I was not aware. The pipeline is using 1/2ms at some places, which works great with 16Mticks/s and yields uint16_t. But with the timing of 72Mticks/s, this will produce an overflow. Best to adjust the ticks/s to something closer to 16Mticks/s. For example the pico runs at 80MHz and then adjust internally accordingly. For STM try to use a timer presaler. Are you testing on HW? |
Add STM32 backend (STM32duino / Arduino_Core_STM32)
Overview
This PR adds a complete STM32 port for FastAccelStepper, targeting the STM32duino toolchain. Step pulses are generated via TIM2/TIM3 compare-match ISR with GPIO BSRR bit-bang, allowing any GPIO pin to be used as a step pin. Deferred queue filling runs in PendSV at the lowest NVIC priority.
The implementation has been reviewed across three audit rounds (R1–R3): critical bug fixes, CI/documentation, and line-by-line code verification against STM32duino core headers.
Supported families
New / modified files
Source (4 files)
src/fas_arch/arduino_stm32.hFAS_STM32define, reentrant-safe PRIMASK IRQ control (fasDisableInterrupts/fasEnableInterrupts),FAS_PSTRsrc/pd_stm32/pd_config.hTICKS_PER_S, queue topology, timing constants, feature flagssrc/pd_stm32/stm32_queue.hStepperQueueclass, GPIO BSRR direction macros,setDirPin()with null-checksrc/pd_stm32/stm32_queue.cppNew example file (1)
examples/StepperDemo/StepperPins_stm32.hCI / build (3 files)
extras/ci/build_matrix.yamlextras/ci/platformio.ini.github/workflows/build_arduino_examples_matrix.ymlKey design details
Timer abstraction (
FAS_TIMERmacros)Timer selection is resolved entirely at compile time:
16-bit wrap-safe CCR write (
fas_tim_set_ccr)STM32F1 (TIM2) and STM32C0 (TIM3) have 16-bit ARR. A naïve
CNT + delayoverflows above 65535. The fix:This correctly wraps: if
cnt=65520, delay=432→ target=416, actual ticks =(65536−65520)+416 = 432. ✓Memory barrier (
FAS_DMB)Cortex-M0/M0+ (F0, G0, L0, C0) do not have
__DMB(). The wrapper uses__DSB()on ARMv6-M and__DMB()on ARMv7-M/ARMv8-M.main:Runtime clock validation
initStepTimer()reads the actual APB1 timer clock viagetTimClock()and compares againstTICKS_PER_S. If mismatched, it setsfas_stm32_clock_error(code 1 = impossible, code 2 = non-integer prescaler) and prints a warning toSerialatengine.init().Two independent clock domains
TICKS_PER_S(user-defined at compile time). Determines all motion parameters.uwTick/ SysTick, fires PendSV every ~3 ms. Does not affect step pulse accuracy.Direction pin: atomic BSRR writes
Direction changes use BSRR (set: low half, clear: high half =
mask << 16), valid on all STM32 families. No ODR read-modify-write race condition.CI test matrix (5 boards)
stm32_f103c8stm32_g070rb__DSB()on M0+, 32-bit TIM2stm32_f401ccstm32_h743ziD2CFGRclock detectionstm32_l476rgUsage
In
platformio.ini, defineTICKS_PER_Smatching the board's APB1 timer clock:Deferred (out of scope for this PR)
README.mdWarning Stop and SetCurrentPosition methods #2: update "TIM2 reserved" note to mention TIM3 on C0 (requires manual edit in fork's README)Change summary